<?php

require_once(getShopBasePath() . 'modules/klarna/api/kreditor.php');

/**
 * Contains most of the functionality that Klarnas module need everywhere in the system.
 *
 * There is no patter in which the functions occur. They will come in the order they where needed.
 *
 * @author Klarna
 */
class klarnaUtil extends oxi18n {

	private $kconfig = '';
	/**
	 * Is the number choosen a problem for you? Dont worry, just change it to any
	 * positive number above 5 and it will work automatically.
	 */
	private $paymentErrorCode = 12379;
	private $error = '';
	private $sucessMessage = '';

	//These arrays are used to decide which fields are to be validated.
	/********************************************
	 *                 INVOICE                  *
	 ********************************************/
	private $reqInGermanyInvoice = array(
									'kigender' => true, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => true,
									'kistreetnr' => false, 'kihouseextension' => false
									);
	private $reqInSwedenInvoice = array(
									'kigender' => false, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => false,
									'kistreetnr' => false, 'kihouseextension' => false
									);
	private $reqInNorwayInvoice = array(
									'kigender' => false, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => false,
									'kistreetnr' => false, 'kihouseextension' => false
									);
	private $reqInFinlandInvoice = array(
									'kigender' => false, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => false,
									'kistreetnr' => false, 'kihouseextension' => false
									);
	private $reqInDenmarkInvoice = array(
									'kigender' => false, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => false,
									'kistreetnr' => false, 'kihouseextension' => false
									);
	private $reqInNetherlandsInvoice = array(
									'kigender' => true, 'kibirth' => true, 'kifon' => false,
									'kimobfon' => true, 'kiuser' => true, 'kistreet' => true,
									'kistreetnr' => false, 'kihouseextension' => false
									);

	/********************************************
	 *               PART PAYMENT               *
	 ********************************************/
	private $reqInGermanyPartPayment = array(
									'kppgender' => true, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => true,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	private $reqInSwedenPartPayment = array(
									'kppgender' => false, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => false,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	private $reqInNorwayPartPayment = array(
									'kppgender' => false, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => false,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	private $reqInFinlandPartPayment = array(
									'kppgender' => false, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => false,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	private $reqInDenmarkPartPayment = array(
									'kppgender' => false, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => false,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	private $reqInNetherlandsPartPayment = array(
									'kppgender' => true, 'kppbirth' => true, 'kppfon' => false,
									'kppmobfon' => true, 'kppuser' => true, 'kppstreet' => true,
									'kppstreetnr' => false, 'kppysalary' => false, 'kpphouseextension' => false
									);
	/********************************************
	 *            SPECIAL CAMPAIGN              *
	 ********************************************/
	private $reqInGermanySpecialCampaign = array(
									'kscgender' => true, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => true,
									'kscstreetnr' => true, 'kscysalary' => false, 'kschouseextension' => false
									);
	private $reqInSwedenSpecialCampaign = array(
									'kscgender' => false, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => false,
									'kscstreetnr' => false, 'kscysalary' => false, 'kschouseextension' => false
									);
	private $reqInNorwaySpecialCampaign = array(
									'kscgender' => false, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => false,
									'kscstreetnr' => false, 'kscysalary' => false, 'kschouseextension' => false
									);
	private $reqInFinlandSpecialCampaign = array(
									'kscgender' => false, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => false,
									'kscstreetnr' => false, 'kscysalary' => false, 'kschouseextension' => false
									);
	private $reqInDenmarkSpecialCampaign = array(
									'kscgender' => false, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => false,
									'kscstreetnr' => false, 'kscysalary' => false, 'kschouseextension' => false
									);
	private $reqInNetherlandsSpecialCampaign = array(
									'kscgender' => true, 'kscbirth' => true, 'kscfon' => false,
									'kscmobfon' => true, 'kscuser' => true, 'kscstreet' => true,
									'kscstreetnr' => false, 'kscysalary' => false, 'kschouseextension' => false
									);

	private $sellTo = '';
	private $userCanBuy = false;

	private $defaultCountrys = array(	'DE' => 0, 'SE' => 0, 'NO' => 0,
	 									'FI' => 0, 'DK' => 0, 'NL' => 0);
													//Isoalpha2 for the country, also found in oxcountry.
													//The real value, which is not zero will be set later.

	/**
	 * The idea behind these two vars: $klarnaInvoiceName and $klarnaPartPaymentName is to make it
	 * easier to change the name of the paymentmethods.
	 * The two places that needs to be changed is here and in the DB.
	 *
	 * NOTE, these names has nothing to do with the names displayed in the view.
	 */
	private $klarnaInvoiceName = 'klarnainvoice';
	private $klarnaPartPaymentName = 'klarnapartpayment';
	private $klarnaSpecialCampaignName = 'klarnaspecialcampaign';

	/**
	 * Unfortunately what is returned from Klarna when getting the pclasses is a number and
	 * not a string of isoalpha2 or isoalpha3 or anything simular. So now its gotta be
	 * translated if wanted to be readable.
	 */
	private $countryList = array(	209 => 'Sweden',
									73  => 'Finland',
									81  => 'Germany',
									164 => 'Norway',
									59  => 'Denmark',
									154 => 'Netherlands');

	/**
	 * Used to get the isoalpha2 from the current user.
	 *
	 * @param oxUser $user the user for which you want the isoalpha2
	 *
	 * @return returns the isoalpha2.
	 */
	public function getISOAlpha2($user) {
		return $this->getUserCountryField($user);
	}

	/**
	 * Used to get a certain field from the user stored in the DB.
	 *
	 * @param oxUser/oxcmp_user $user The given user.
	 * @param String $field the wanted field, defaults to oxisoalpha2.
	 *
	 * @return a field from the DB.
	 */
	public function getUserCountryField($user, $field = '') {
		if(!$user) {
			return -1;
		}

		if(!$field) {
			$field = 'oxisoalpha2';
		}

		$oxCountry = oxNew('oxcountry');
		$oxCountry->load($user->oxuser__oxcountryid->value);
		$temp = 'oxcountry__' . $field;
		return $oxCountry->$temp->value;
	}

	/**
	 * Converts a oxPrice value to another currency.
	 *
	 * @param oxPrice $oPrice the oxPrice to be converted
	 * @param unknown_type $oCur the currency rate.
	 *
	 * @return the converted oxPrice object.
	 */
	public function applyCurrency(oxPrice $oPrice, $oCur = null ) {
		if ( !$oCur ) {
			$oCur = $this->getConfig()->getActShopCurrencyObject();
		}

		$oPrice->multiply($oCur->rate);
	}

	/**
	 * Used to create a oxPrice object. Also converts the price into the correct currency.
	 *
	 * @param double $price the price in euro.
	 * @param double $vat the vat.
	 * @param oxUser the user Object. So that a vat can be determined.
	 *
	 * @return oxPrice object.
	 */
	public function createPrice($price, $vat) {
		if(!$vat) {
			$vat = $this->getVat();
		}

		$oxprice = oxNew('oxprice', $price);
		$oxprice->setVat($vat);
		$this->applyCurrency($oxprice);
		return $oxprice;
	}

	/**
	 * Returns the vat for the current country
	 *
	 * @param string $isoalpha2 the country code of the country for which you want the vat.
	 * @param oxlist $oxlist the list containing all items, only needed for sweden.
	 */
	public function getVat($oxlist = '') {
		$kconfig = $this->getKlarnaConfig();
		$country = $kconfig->klarnaconfig__vendorcountry->value;

		if($country == 'DE') {
			return 19;
		} else if($country == 'SE') {
			$withTax = 0;
			$withoutTax = 0;
			foreach($oxlist as $obj) {
				$withTax += $obj->oxorderarticles__oxbprice->value;
				$withoutTax += $obj->oxorderarticles__oxnprice->value;
			}

			if($withTax != 0 && $withoutTax != 0) {
				return round((($withTax/$withoutTax) -1), 5)*100;
			}

			return 25;
		} else if ($country == 'NO') {
			return 25;
		} else if ($country == 'FI') {
			return 23;
		} else if ($country == 'DK') {
			return 25;
		} else if ($country == 'NL') {
			return 19;
		}

		return 0;
	}

	/**
	 * Used to transform the birthdate that can be put in on the register page.
	 *
	 * @param unknown_type $date
	 */
	public function transformDate($date, $user) {
		$country = $this->getISOAlpha2($user);
		if($country == 'DE' || $country == 'NL') {
			return strftime("%d%m%Y", strtotime($date));
		} else if($country == 'SE') {
			return strftime("%y%m%d", strtotime($date));
		} else if($country == 'NO' || $country == 'FI' || $country == 'DK') {
			return strftime("%d%m%y", strtotime($date));
		}

		return $date;
	}

	public function getPaymentErrorCode() {
		return $this->paymentErrorCode;
	}

	/**
	 * Saves a error in the error containers.
	 *
	 * @param string $error
	 */
	public function saveError($error) {
		$this->error = $error;
		OxSession::setVar('klarna_error', $error);
	}

	/**
	 * Loads the error and then immediately empties it. This is because otherwise it will confuse
	 * the system when going backwards in the checkoutsteps. You shouldnt get a error when you havent
	 * done anything.
	 */
	public function loadError() {
		if(!$this->error) {
			$this->error = OxSession::getVar('klarna_error');
		}
		$theError = $this->error;
		$this->emptyError();

		return $theError;
	}

	/**
	 * Used to empty the error containers.
	 */
	public function emptyError() {
		$this->error = '';
		oxSession::deleteVar('klarna_error');
	}

	/**
	 * Saves a Success Message in the SM containers.
	 *
	 * @param string $error
	 */
	public function saveSM($sucessMessage) {
		$this->sucessMessage = $sucessMessage;
		OxSession::setVar('sucessMessage', $sucessMessage);
	}

	/**
	 * Loads the Success Message and then immediately empties it. This is because otherwise it
	 * will confuse the system when going backwards in the checkoutsteps. You shouldnt get a
	 * error when you havent done anything.
	 */
	public function loadSM() {
		if(!$this->sucessMessage) {
			$this->sucessMessage = OxSession::getVar('sucessMessage');
		}

		$theSM = $this->sucessMessage;
		$this->emptySM();

		return $theSM;
	}

	/**
	 * Used to empty the SM containers.
	 */
	public function emptySM() {
		$this->sucessMessage = '';
		oxSession::deleteVar('sucessMessage');
	}

	/**
	 * Returns a country specific array, used to decide which fields that shall be validated.
	 *
	 * @param oxUser $user
	 *
	 * @return returns a array with the required fields. Or a empty array if the given countries required
	 * fields isn't specified.
	 */
	public function getValidationArrayInvoice($user) {
		$country = $this->getISOAlpha2($user);
		if($country == 'DE') {
			return $this->reqInGermanyInvoice;
		} else if($country == 'SE') {
			return $this->reqInSwedenInvoice;
		} else if($country == 'NO') {
			return $this->reqInNorwayInvoice;
		} else if($country == 'FI') {
			return $this->reqInFinlandInvoice;
		} else if($country == 'DK') {
			return $this->reqInDenmarkInvoice;
		} else if($country == 'NL') {
			return $this->reqInNetherlandsInvoice;
		}

		return array();
	}

	/**
	 * Returns a country specific array, used to decide which fields that shall be validated.
	 *
	 * @param oxUser $user
	 *
	 * @return returns a array with the required fields. Or a empty array if the given countries required
	 * fields isn't specified.
	 */
	public function getValidationArrayPartPayment($user) {
		$country = $this->getISOAlpha2($user);
		if($country == 'DE') {
			return $this->reqInGermanyPartPayment;
		} else if($country == 'SE') {
			return $this->reqInSwedenPartPayment;
		} else if($country == 'NO') {
			return $this->reqInNorwayPartPayment;
		} else if($country == 'FI') {
			return $this->reqInFinlandPartPayment;
		} else if($country == 'DK') {
			return $this->reqInDenmarkPartPayment;
		} else if($country == 'NL') {
			return $this->reqInNetherlandsPartPayment;
		}

		return array();
	}

	public function getValidationArraySpecialCampaign($user) {
		$country = $this->getISOAlpha2($user);
		if($country == 'DE') {
			return $this->reqInGermanySpecialCampaign;
		} else if($country == 'SE') {
			return $this->reqInSwedenSpecialCampaign;
		} else if($country == 'NO') {
			return $this->reqInNorwaySpecialCampaign;
		} else if($country == 'FI') {
			return $this->reqInFinlandSpecialCampaign;
		} else if($country == 'DK') {
			return $this->reqInDenmarkSpecialCampaign;
		} else if($country == 'NL') {
			return $this->reqInNetherlandsSpecialCampaign;
		}
	}

	/**
	 * Used to get the database table klarnaconfig.
	 *
	 * @return Returns the database equivalent.
	 */
	public function getKlarnaConfig() {
		if($this->kconfig) {
			return $this->kconfig;
		}

		$myConfig  = $this->getConfig();
		$soxId = $myConfig->getShopId();

		$klarnaconfig = oxNew('klarnaconfig');
		$klarnaconfig->load($soxId);

		return $klarnaconfig;
	}

	/**
	 * Used to controll if a given user can use Klarnas payment option. This is specifically checked
	 * against the sellto list edited in the admin view. If the user is not from a sellto country
	 * this will return false.
	 *
	 * @param oxUser $user
	 *
	 * @return true if the user is from a sellto country.
	 */
	public function isUserFromSellToCountry($user) {
		if($this->userCanBuy) {
			//To save time and make less use of the DB.
			return true;
		}

		if(!$this->sellTo) {
			$this->sellTo = array();
			$temp = $this->getKlarnaConfig()->klarnaconfig__sellto->value;
			$temp2 = oxUtils::getInstance()->assignValuesFromText($temp);

			foreach($temp2 as $field) {
				$this->sellTo[substr($field->name, 2)] = ($field->name[0] ? 1 : 0);
			}
		}

		$userCountry = $this->getISOAlpha2($user);
		if($this->sellTo[$userCountry]) {
			$this->userCanBuy = true;
			return true;
		}
		return false;
	}

	public function getIName() {
		return $this->klarnaInvoiceName;
	}

	public function getPPName() {
		return $this->klarnaPartPaymentName;
	}

	public function getSCName() {
		return $this->klarnaSpecialCampaignName;
	}

	/**
	 * Returns the invoice fee for a specific country. This is set in the admin view.
	 *
	 * @param oxUser $user
	 *
	 * @return returns the invoicefee.
	 */
	public function getInvoiceFee($user) {
		$country = $this->getISOAlpha2($user);
		$kconfig = $this->getKlarnaConfig();
		if($country == 'DE') {
			return $kconfig->klarnaconfig__invoicefeede->value;
		} else if($country == 'SE') {
			return $kconfig->klarnaconfig__invoicefeese->value;
		} else if($country == 'NO') {
			return $kconfig->klarnaconfig__invoicefeeno->value;
		} else if($country == 'FI') {
			return $kconfig->klarnaconfig__invoicefeefi->value;
		} else if($country == 'DK') {
			return $kconfig->klarnaconfig__invoicefeedk->value;
		} else if($country == 'NL') {
			return $kconfig->klarnaconfig__invoicefeenl->value;
		}
	}

	/**
	 * Downloads the pclasses from Klarnas server and then stores them in the DB.
	 * Also calls for the creation of the pclasses.php file.
	 */
	public function getNewPclasses() {
		$kconfig = $this->getKlarnaConfig();

		$myConfig  = $this->getConfig();
		$soxId = $myConfig->getShopId();

		$oDb = oxDb::getDb();
		$q1 = "DELETE FROM klarnapclasses WHERE oxshopid = '" . $soxId . "'";
		$oDb->execute($q1);

		$eid = $kconfig->klarnaconfig__eid->value;
		$secret = $kconfig->klarnaconfig__secret->value;
		$currencys = array( 209 => 'KRED_SEK',
							73  => 'KRED_EUR',
							81  => 'KRED_EUR',
							154 => 'KRED_EUR',
							164 => 'KRED_NOK',
							59  => 'KRED_DKK');
		$temp = array();
		$temp2 = array();
		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_SE']]],
						$secret, $GLOBALS['KRED_ISO3166_SE'], $GLOBALS['KRED_ISO639_SV'],
						$temp);
						$temp2[] = $temp; //Sweden
		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_FI']]],
						$secret, $GLOBALS['KRED_ISO3166_FI'], $GLOBALS['KRED_ISO639_FI'],
						$temp);
						$temp2[] = $temp; //Finland
		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_DE']]],
						$secret, $GLOBALS['KRED_ISO3166_DE'], $GLOBALS['KRED_ISO639_DE'],
						$temp);
						$temp2[] = $temp; //Germany
		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_NO']]],
						$secret, $GLOBALS['KRED_ISO3166_NO'], $GLOBALS['KRED_ISO639_NO'],
						$temp);
						$temp2[] = $temp; //Norway
		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_DK']]],
						$secret, $GLOBALS['KRED_ISO3166_DK'], $GLOBALS['KRED_ISO639_DA'],
						$temp);
						$temp2[] = $temp; //Denmark

		fetch_pclasses(	$eid, $GLOBALS[$currencys[$GLOBALS['KRED_ISO3166_NL']]],
						$secret, $GLOBALS['KRED_ISO3166_NL'], $GLOBALS['KRED_ISO639_NL'],
						$temp);
						$temp2[] = $temp; //Netherlands

		$array = array();
		foreach($temp2 as $subarray) {
			foreach($subarray as $subsubarray) {
				$array[] = $subsubarray;
			}
		}
		for($i = 0; $i < count($array); $i++) {
			if(!is_numeric($array[$i][2])) {
				continue;
			}

			$q2 = "	INSERT INTO klarnapclasses (oxshopid, pclassid, description, months,
					startfee, handlingfee, interest, minamount, currency, type, country) ";
			$q2 .= "VALUES ('$soxId', " . $array[$i][0] . ", '" . $array[$i][1] . "', " .
							$array[$i][2] . ", " . $array[$i][3] . ", " . $array[$i][4] . ", " .
							$array[$i][5] . ", " . $array[$i][6] . ", '" .
							$currencys[$array[$i][7]] .  "' , " . $array[$i][8] . ", " . $array[$i][7] . ")";
			$oDb->execute($q2);
		}

		if(!create_pclasses_file($eid, '', $secret)) {
			//This is being done so that you as a user wont be confused.
			$q1 = "DELETE FROM klarnapclasses WHERE oxshopid = '" . $soxId . "'";
			$oDb->execute($q1);
			$lang = oxLang::getInstance()->translateString('KLARNA_PCLASSES_FILE_PERMISSION');
		}
	}

	/**
	 * Used to get the DB stored pclasses.
	 *
	 * TODO Replace curreny with country. When the new pclass method is done.
	 *
	 * @param String $shopid, default -> fetch it. Used to get a diffrent shops pclasses.
	 * @param int $pclassid, default -> wildcard, used to get a specific pclass.
	 * @param oxUser $user, default -> wildcard, used to get all pclasses for a given currency.
	 *
	 * @return returns a oxlist with the pclasses.
	 */
	public function getPclasses($shopid = '', $pclassid = '', $user = '') {
		if(!$shopid) {
			$myConfig  = $this->getConfig();
			$shopid = $myConfig->getShopId();
		}

		if($pclassid && is_numeric($pclassid)) {
			$pclassid = " AND pclassid = " . $pclassid;
		}

		if($user) {
			$country = " AND country = " . $this->getCountryNumber($user);
		}

		$oGroups = oxNew('oxlist');
		$oGroups->init('klarnapclasses');
		$oGroups->selectString( "SELECT * FROM klarnapclasses WHERE oxshopid = '" . $shopid . "'" . $pclassid . $country . ";");
		return $oGroups;
	}

	/**
	 * Checks if there is any valid pclasses and if it then shall be shown or not.
	 *
	 * A check may be needed to add to see if the basket amount is over 100eur if you can have pclasses without
	 * account.
	 *
	 * @param oxUser $user the user to determine which pclasses that shall be checked on.
	 * @param $currency used to decide if the payment shall be shown or not.
	 *
	 * @return returns true of false if the payment shall be shown or not.
	 */
	public function showKPP($user, $currency) {
		$myConfig  = $this->getConfig();
		$shopid = $myConfig->getShopId();

		$country = " AND country = " . $this->getCountryNumber($user);

//		$oDB = oxDb::getDb(true);
//		$sql = "SELECT * FROM klarnapclasses WHERE oxshopid = '" . $shopid . "'" . $country . " AND type != 2;";
		//getRealBasketCost() {showPclass($pclass, $user, $currency, $basketcost)

		$oGroups = oxNew( "oxlist" );
		$oGroups->init( 'klarnapclasses' );
		$oGroups->selectString("SELECT * FROM klarnapclasses WHERE oxshopid = '" . $shopid . "'" . $country . " AND type != 2;");

		$showKpp = false;
		foreach($oGroups as $pclass) {
			if($this->showPclass($pclass, $user,
											$currency->name, $this->getRealBasketCost())) {
				$showKpp = true;
			}
		}

		return $showKpp;
	}

	/**
	 * Checks if there is any valid pclasses and if it then shall be shown or not.
	 *
	 * @param oxUser $user the user to determine which pclasses that shall be checked on.
	 */
	public function showKSC($user) {
		$myConfig  = $this->getConfig();
		$shopid = $myConfig->getShopId();

		$country = " AND country = " . $this->getCountryNumber($user);

		$oDB = oxDb::getDb(true);
		$sql = "SELECT * FROM klarnapclasses WHERE oxshopid = '" . $shopid . "'" . $country . " AND type = 2;";
		return $oDB->getOne($sql) ? true : false;
	}

	/**
	 * Determines if the YSalary field in the view shall be shown. Returns a bool with the decision.
	 *
	 * @param oxUser $user The user used to determine what country the user is from.
	 * @param double $basketcost what is the basketcost at the moment? minus payment fee.
	 *
	 * @return false or true depending on if the field shall be visible.
	 */
	public function showYSalary($user, $basketcost) {
		$country = $this->getISOAlpha2($user);
		$kconfig = $this->getKlarnaConfig();
		if(	$country == 'DE' || $country == 'SE' || $country == 'NO'
			|| $country == 'FI' || $country == 'DK' || $country == 'NL') {

			$temp = 'klarnaconfig__ysalary' . strtolower($country);
			if($kconfig->$temp->value == -1) {
				return false;
			} else {
				$price = $this->createPrice($kconfig->$temp->value);
				return $basketcost >= $price->getBruttoPrice() ? true : false;
			}
		}

		return false;
	}
	/**
	 * First creates the table(if needed), then inserts a field into the table and then
	 * inits a KlarnaInstall object and returns it.
	 *
	 * @return KlarnaInstall returns a initiated KlarnaInstall object ready to use.
	 */
	public function getInstallObject() {
		$myConfig = $this->getConfig();
		$shopId = $myConfig->getShopId();

		$oDB = oxDb::getDb(true);

		$sql = "CREATE TABLE IF NOT EXISTS klarnainstall (
					OXID CHAR(32) PRIMARY KEY,
					DONE TINYINT(1) NOT NULL DEFAULT 0,
					CREATETABLES TINYINT(1) NOT NULL DEFAULT 0,
					INSERTPAYMENTS TINYINT(1) NOT NULL DEFAULT 0,
					ADDUSERGROUPS TINYINT(1) NOT NULL DEFAULT 0,
					ADDSHIPPINGTYPES TINYINT(1) NOT NULL DEFAULT 0,
					ADDCOUNTRIES TINYINT(1) NOT NULL DEFAULT 0,
					AMODULEINOXCONFIG TINYINT(1) NOT NULL DEFAULT 0,
					ACURRENCIES TINYINT(1) NOT NULL DEFAULT 0,
					SAVECONFIG TINYINT(1) NOT NULL DEFAULT 0,
					DEFAULTCOUNTRY TINYINT(1) NOT NULL DEFAULT 0
				);";
		$oDB->execute($sql);

		$sql = "INSERT IGNORE INTO klarnainstall (OXID) VALUES ('$shopId');";
		$oDB->execute($sql);

		$installer = oxNew('klarnainstall');
		$installer->load($shopId);

		return $installer;
	}

	/**
	 * Creates the sellto string that will be persisted in the DB.
	 *
	 * Utilizes functionality from oxid.
	 *
	 * @return String returns the string that will be stored in the DB.
	 */
	public function createSellToString($sellTo, $countries) {
		$oDB = oxDb::getDb(true);
		foreach($countries as $key => &$value) {
			$sql = "SELECT OXISOALPHA2 from oxcountry WHERE OXTITLE = '$value';";
			$value = $oDB->getOne($sql);
		}

		$sellToBefore = oxUtils::getInstance()->assignValuesFromText( $sellTo );

		$temp = '';
		foreach ( $sellToBefore as $oField) {
			if($countries) {
				foreach($countries as $oField2) {
					if($oField2 == substr($oField->name, 2)) {
						$temp = true;
					}
				}
			}
			$oField->name[0] = $temp ? '1' : '0';
			$temp = '';
		}

		$sellToAfter = '';
		foreach ( $sellToBefore as $oField) {
			$sellToAfter .= $oField->name . "__@@";
		}

		return $sellToAfter;
	}

	/**
	 * Creates a url that points to Klarna's loggos.
	 *
	 * @return String returns a complete url for the image.
	 */
	public function getImageUrl($user, $paymentType) {
		$country = strtolower($this->getISOAlpha2($this->getUser()));
		$baseurl = "http://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).'/modules/klarna/images/';

		if(strtolower($paymentType) == 'ki') {
			return $baseurl . 'klarnainvoice_' . $country . '.png';
		} elseif(strtolower($paymentType) == 'kpp') {
			return $baseurl . 'klarnapartpayment_' . $country . '.png';
		} elseif(strtolower($paymentType) == 'ksc') {
			return $baseurl . 'klarnasc.png';
		} else {
			return $baseurl . 'klarna.png';
		}
	}

	/**
	 * Unfortunately what is returned from Klarna when getting the pclasses is a number and
	 * not a string of isoalpha2 or isoalpha3 or anything simular. So now its gotta be
	 * translated if wanted to be readable.
	 *
	 * @param int $id id of the countries name.
	 *
	 * @return String the representative equivalent of the country id.
	 */
	public function transformCountryId($id) {
		return $this->countryList[$id];
	}

	/**
	 * Calculates the montly payment cost for a product.
	 * If the user is empty the default country will be used.
	 *
	 * @param double $sum the product cost of the item in question.
	 * @param String $user oxUser object to determine country origin for the pclass. Got default value.
	 *
	 * @return int lowest monthly payment cost for a product if you use Klarna Part Payment.
	 */
	public function getMontlyProductCost($sum, $user) {
		$sum = str_replace(',', '.', $sum);// 8,9*10 = 80.

		$myConfig  = $this->getConfig();
		$shopid = $myConfig->getShopId();

		$countries = array();
		if(!$user) {
			$countries[] = $GLOBALS['KRED_ISO3166_'.$this->getDefaultCountry()];
		} else {
			$countries[] = $this->getCountryNumber($user);
		}

		$lowest = '';
		foreach($countries as $key => $value) {
			$oGroups = oxNew('oxlist');
			$oGroups->init('klarnapclasses');
			$oGroups->selectString( "SELECT * FROM klarnapclasses WHERE OXSHOPID = '$shopid' AND COUNTRY = " . $value . ";");

			foreach($oGroups as $item) {
				getMontlyCost($sum*100, $item->klarnapclasses__pclassid->value, 1, $result);
				if(!$lowest) {
					$lowest = $result;
				}
				$lowest = $lowest < $result ? $lowest : $result;
			}
		}

		return ceil($lowest/100);
	}

	/**
	 * Used to fetch the Klarna system country number.
	 *
	 * @param oxUser $user The user from which the country number shall be found
	 *
	 * @return int the country number equivalent for isoalpha2.
	 */
	public function getCountryNumber($user) {
		$userCountry = $this->getISOAlpha2($user);
		return $GLOBALS['KRED_ISO3166_'.$userCountry];
	}

	/**
	 * Calculates the montly cost.
	 *
	 * @param double $sum, the sum for which the calculation shall be made.
	 * @param int $pclassid the idnumber of the pclass.
	 * @param int $i 0 is default and for the checkout page, 1 for product page.
	 *
	 * @return int returns the monthly cost for a given sum.
	 */
	public function calcTheMontlyCost($sum, $pclassid, $i = 0) {
		$sum = str_replace(',', '.', $sum);// 8,9*10 = 80.
		getMontlyCost($sum*100, $pclassid, $i, $result);
		return ceil($result/100);
	}

	/**
	 * Returns the basket cost without a eventual payment cost that will be stored in the
	 * session, but not wanted when calculating e.g. monthly payment cost.
	 *
	 * @return double basket cost.
	 */
	public function getRealBasketCost() {
		$totalPrice = $this->getSession()->getBasket()->getPrice()->getBruttoPrice();
		if($this->getSession()->getBasket()->getCosts('oxpayment')) {
			$totalPrice -= $this->getSession()->getBasket()->getCosts('oxpayment')->getBruttoPrice();
		}

		return $totalPrice;
	}

	public function getDefaultCountries() {
		return $this->defaultCountrys;
	}

	public function getDefaultCountry() {
		return $this->getKlarnaConfig()->klarnaconfig__defaultcountry->value;
	}

	/**
	 * Used to get a country id for the terms of use.
	 *
	 * @param oxUser $user The user from which the country number shall be found
	 *
	 * @return int the country number equivalent for isoalpha2.
	 */
	public function getCountry($user) {
		if($user) {
			return $this->getISOAlpha2($user);
		} else {
			return $this->getDefaultCountry();
		}
	}

	/**
	 * Used for deciding if a pclass shall be visible in the checkout or not.
	 *
	 * @param KlarnaPclass $pclass The pclass for which  the check shall be done.
	 * @param oxUser $user can this user use this pclass?
	 * @param oxStdClass $currency the current currency.
	 * @param double $basketcost the basketcost.
	 *
	 * @return bool true of false depending on weather it shall be shown or not.
	 */
	public function showPclass($pclass, $user, $currency, $basketcost) {
		$isoa2 = $this->getISOAlpha2($user);
		$sum = 0;
		switch ($isoa2) {
			case 'SE':
			case 'NO':
			case 'DK':
				$sum = 1000;
				break;
			default:
				$sum = 100;	;
			break;
		}

		if($pclass->klarnapclasses__type->value == 2) {
			return false;
		} elseif ($pclass->klarnapclasses__type->value == 0 && $basketcost < $sum) {
			return false;
		}

		return $this->showPaymentFull($isoa2, $currency);
	}

	/**
	 * Does the same as showPclass but instead check for type = 2.
	 *
	 * @param KlarnaPclass $pclass The pclass for which  the check shall be done.
	 * @param oxUser $user can this user use this pclass?
	 * @param oxStdClass $currency the current currency.
	 * @param double $basketcost the basketcost.
	 *
	 * @return bool true of false depending on weather it shall be shown or not.
	 */
	public function showSpecialPclass($pclass, $user, $currency, $basketcost) {
		if($pclass->klarnapclasses__type->value != 2) {
			return false;
		}

		return $this->showPaymentFull($this->getISOAlpha2($user), $currency);
	}

	/**
	 * Used to decide wether or not the payment options shall be displayed, also,
	 * This is only used to decide if the payment shall not be shown due to wrong currency.
	 * If a wrong currency is used but the user is from a sellto country then a miniature
	 * Klarna payment is shown, but without the fields.
	 *
	 * ALSO USED FOR showSpecialPclass AND showPclass.
	 *
	 * @param String $country
	 * @param String $currency
	 *
	 * @return bool true if country and currency is correct.
	 */
	public function showPaymentFull($country, $currency) {
		if($currency instanceof oxStdClass) {
			$currency = $currency->name;
		}

		if(($country == 'DE' || $country == 'FI' || $country == 'NL') && $currency == 'EUR') {
			return true;
		} elseif ($country == 'SE' && $currency == 'SEK') {
			return true;
		} elseif ($country == 'NO' && $currency == 'NOK') {
			return true;
		} elseif ($country == 'DK' && $currency == 'DKK') {
			return true;
		}

		return false;
	}

	/**
	 * Saves a Email Success Message in the emailSM container.
	 *
	 * @param string $error
	 */
	public function saveEmailSM($sucessEmailMessage) {
		OxSession::setVar('sucessEmailMessage', $sucessEmailMessage);
	}

	/**
	 * Loads the Success Message for the Email and then immediately empties it. This is because
	 * you shall not use it twice.
	 */
	public function loadEmailSM() {
		$temp = OxSession::getVar('sucessEmailMessage');
		$this->emptyEmailSM();

		return $temp;
	}

	/**
	 * Used to empty the EmailSM container.
	 */
	public function emptyEmailSM() {
		oxSession::deleteVar('sucessEmailMessage');
	}

	/**
	 * This is part of the installation process. It was moved here as it is also a part of the updating process.
	 * And because it is so big, I moved it here instead of having two copies, which anyways aint good.
	 */
	public function addNewCurrencies() {
		$myConfig = $this->getConfig();
		$shopId = $myConfig->getShopId();
		$currenciesToAdd = array(
								'SEK' => 0,
								'NOK' => 0,
								'DKK' => 0,
								);

		$aCurrencies = oxConfig::getInstance()->getConfigParam('aCurrencies');

		/**
		 * This part takes care of cases when a class is already present in the modules
		 * extension list i.e. cases when a class is alerady being extended and also making sure
		 * that klarnas classes aint double extending the superclasses.
		 */
		$xml = simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
		$mainCurr = '';
		if(!empty($aCurrencies)) {//$currenciesToAdd
			foreach ($aCurrencies as $aCurrenciesName) {
				$currencyInfo = preg_split('/[@]/', $aCurrenciesName);

				//Begins at one, as it contains a space.
				$mainCurr = (substr($currencyInfo[1], 1, 4) == '1.00') ? $currencyInfo[0] : $mainCurr;

				if (in_array($currencyInfo[0], $currenciesToAdd)) {
					unset($currenciesToAdd[$currencyInfo[0]]);
					continue;
				}
			}
		}

		$rate = '1';
		if($mainCurr == 'EUR') {
		} else if($mainCurr != '') {
			$inXMLDocument = false;

			foreach($xml->Cube->Cube->Cube as $child) {
				if($mainCurr == $child['currency']) {
					$inXMLDocument = true;
					$rate = $child['rate'];
				}
			}

			if(!$inXMLDocument) {
				//Nothing can be done, the currency aint in the xml document.
				return false;
			}

			//For some reason the decimals doesnt work without substr on $rate.
			$rate = 1/substr($rate, 0, 6);
		} else {
			//Nothing can be done, no main currency, the customer will have to set the rate by them selfs.
			return false;
		}

		foreach($xml->Cube->Cube->Cube as $child) {
			if(	($child['currency'] == 'SEK' && in_array($child['currency'], $currenciesToAdd)) ||
				($child['currency'] == 'NOK' && in_array($child['currency'], $currenciesToAdd)) ||
				($child['currency'] == 'DKK' && in_array($child['currency'], $currenciesToAdd))
				) {

				//For some reason the decimals doesnt work without substr on child['rate'].
				$aCurrencies[] = $child['currency'] . '@ ' .
							substr($rate*substr($child['rate'], 0, 6), 0, 6) . '@ .@  @ kr@ 2';
			}
		}

		$myConfig = $this->getConfig();
		$myConfig->saveShopConfVar( "arr", "aCurrencies", $aCurrencies, $shopId );
		return true;
	}

	public function getKredVersion() {
		return $GLOBALS['CLIENT_VSN'];
	}
}
?>